<!DOCTYPE html>
<html lang="zh-CN">
  <head>
  <meta charset="UTF-8">
  <meta 
    name="viewport"
    content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
  <meta 
    http-equiv="X-UA-Compatible" 
    content="ie=edge">
  <meta 
    name="theme-color" 
    content="#fff" 
    id="theme-color">
  <meta 
    name="description" 
    content="hexoDemo用于介绍如何使用hexo">
  <link 
    rel="icon" 
    href="/">
  <title>01-前端性能分析工具和指标</title>
  
    
      <meta 
        property="og:title" 
        content="01-前端性能分析工具和指标">
    
    
      <meta 
        property="og:url" 
        content="https://zwl5670.gitee.io/2014/08/01/14-%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/01-%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90%E5%B7%A5%E5%85%B7%E5%92%8C%E6%8C%87%E6%A0%87/index.html">
    
    
      <meta 
        property="og:img" 
        content="https://img.songhn.com/img/Y67gdd.png">
    
    
      <meta 
        property="og:img" 
        content="hexoDemo用于介绍如何使用hexo">
    
    
      <meta 
        property="og:type" 
        content="article">
      <meta 
        property="og:article:published_time" 
        content="2014-08-01">
      <meta 
        property="og:article:modified_time" 
        content="2023-03-14">
      <meta 
        property="og:article:author" 
        content="zwl5670">
      
        
          <meta 
            property="og:article:tag" 
            content="性能优化">
        
      
    
  
  
  <link rel="preload" href="//at.alicdn.com/t/font_1946621_i1kgafibvw.css" as="style" >
  <link rel="preload" href="//at.alicdn.com/t/font_1952792_89b4ac4k4up.css" as="style" >
  <link rel="preload" href="/css/main.css" as="style" >
  
  <link rel="modulepreload" href="//instant.page/5.1.0">
  
  <link rel="stylesheet" href="/css/main.css">
  
  <link rel="stylesheet" href="//at.alicdn.com/t/font_1946621_i1kgafibvw.css">
  
  <link rel="stylesheet" href="//at.alicdn.com/t/font_1952792_89b4ac4k4up.css">
  
  
  
    <link rel="stylesheet" href="/js/lib/lightbox/baguetteBox.min.css">
  
  <script>
    function loadScript(url, cb) {
      var script = document.createElement('script');
      script.src = url;
      if (cb) script.onload = cb;
      script.async = true;
      document.body.appendChild(script);
    }
    function loadCSS(href, data, attr) {
      var sheet = document.createElement('link');
      sheet.ref = 'stylesheet';
      sheet.href = href;
      sheet.dataset[data] = attr;
      document.head.appendChild(sheet);
    }
    function changeCSS(cssFile, data, attr) {
      var oldlink = document.querySelector(data);
      var newlink = document.createElement("link");
      newlink.setAttribute("rel", "stylesheet");
      newlink.setAttribute("href", cssFile);
      newlink.dataset.prism = attr;
      document.head.replaceChild(newlink, oldlink);
    }
  </script>
  
    
  
  <script>
    // control reverse button
    var reverseDarkList = {
      dark: 'light',
      light: 'dark'
    };
    var themeColor = {
      dark: '#1c1c1e',
      light: '#fff'
    }
    // get the data of css prefers-color-scheme
    var getCssMediaQuery = function() {
      return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
    };
    // reverse current darkmode setting function
    var reverseDarkModeSetting = function() {
      var setting = localStorage.getItem('user-color-scheme');
      if(reverseDarkList[setting]) {
        setting = reverseDarkList[setting];
      } else if(setting === null) {
        setting = reverseDarkList[getCssMediaQuery()];
      } else {
        return;
      }
      localStorage.setItem('user-color-scheme', setting);
      return setting;
    };
    // apply current darkmode setting
  </script>
  
    <script>
      var setDarkmode = function(mode) {
      var setting = mode || localStorage.getItem('user-color-scheme');
      if(setting === getCssMediaQuery()) {
        document.documentElement.removeAttribute('data-user-color-scheme');
        localStorage.removeItem('user-color-scheme');
        document.getElementById('theme-color').content = themeColor[setting];
        document.getElementById('theme-color').dataset.mode = setting;
      } else if(reverseDarkList[setting]) {
        document.documentElement.setAttribute('data-user-color-scheme', setting);
        document.getElementById('theme-color').content = themeColor[setting];
        document.getElementById('theme-color').dataset.mode = setting;
      } else {
        document.documentElement.removeAttribute('data-user-color-scheme');
        localStorage.removeItem('user-color-scheme');
        document.getElementById('theme-color').content = themeColor[getCssMediaQuery()];
        document.getElementById('theme-color').dataset.mode = getCssMediaQuery();
      }
    };
    setDarkmode();
    </script>
  
  
  
    <link rel="preload" href="/js/lib/lightbox/baguetteBox.min.js" as="script">
    <link rel="preload" href="/js/lib/lightbox/baguetteBox.min.css" as="style" >
  
  
    <link rel="preload" href="/js/lib/lozad.min.js" as="script">
  
  
  
  
  
  
<meta name="generator" content="Hexo 6.3.0"></head>

  <body>
    <div class="wrapper">
       
      <nav class="navbar">
  <div class="navbar-logo">
    <a class="navbar-logo-main" href="/">
      
      <span class="navbar-logo-dsc">前端面试</span>
      </a>
  </div>
  <div class="navbar-menu">
    
      <a 
        href="/" 
        class="navbar-menu-item">
        
          首页
        
      </a>
    
      <a 
        href="/archives" 
        class="navbar-menu-item">
        
          归档
        
      </a>
    
      <a 
        href="/tags" 
        class="navbar-menu-item">
        
          标签
        
      </a>
    
      <a 
        href="/categories" 
        class="navbar-menu-item">
        
          分类
        
      </a>
    
      <a 
        href="/about" 
        class="navbar-menu-item">
        
          关于
        
      </a>
    
      <a 
        href="/links" 
        class="navbar-menu-item">
        
          友链
        
      </a>
    
    <button 
      class="navbar-menu-item darknavbar navbar-menu-btn" 
      aria-label="Toggle dark mode"
      id="dark">
      <i class="iconfont icon-weather"></i>
    </button>
    <button 
      class="navbar-menu-item searchnavbar navbar-menu-btn" 
      aria-label="Toggle search"
      id="search">
      <!-- <i 
        class="iconfont icon-search" 
        style="font-size: 1.2rem; font-weight: 400;">
      </i> -->
      <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img"
        class="iconify iconify--ion" width="28" height="28" preserveAspectRatio="xMidYMid meet" viewBox="0 0 512 512">
        <path fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="28"
          d="M256 80a176 176 0 1 0 176 176A176 176 0 0 0 256 80Z"></path>
        <path fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="28"
          d="M232 160a72 72 0 1 0 72 72a72 72 0 0 0-72-72Z"></path>
        <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="28"
          d="M283.64 283.64L336 336"></path>
      </svg>
    </button>
  </div>
</nav> 
      
      <div 
        id="local-search" 
        style="display: none">
        <input
          class="navbar-menu-item"
          id="search-input"
          placeholder="请输入搜索内容..." />
        <div id="search-content"></div>
      </div>
      
      <div class="section-wrap">
        <div class="container">
          <div class="columns">
            <aside class="left-column">
              
              <div class="card card-author">
                
  <img 
    src="https://img.songhn.com/img/Y67gdd.png" 
    class="author-img"
    width="88"
    height="88"
    alt="author avatar">

<p class="author-name">zwl5670</p>
<p class="author-description">前端学习资料</p>
<div class="author-message">
  <a 
    class="author-posts-count" 
    href="/archives">
    <span>215</span>
    <span>文章</span>
  </a>
  <a 
    class="author-categories-count" 
    href="/categories">
    <span>14</span>
    <span>分类</span>
  </a>
  <a 
    class="author-tags-count" 
    href="/tags">
    <span>14</span>
    <span>标签</span>
  </a>
</div>

              </div>
               <div class="sticky-tablet">
  
  
    <article class="display-when-two-columns spacer">
      <div class="card card-content toc-card">
        <div class="toc-header">
  <i 
    class="iconfont icon-menu" 
    style="padding-right: 2px;">
  </i>目录
</div>
<ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%80%A7%E8%83%BD%E6%8C%87%E6%A0%87%E5%92%8C%E4%BC%98%E5%8C%96%E7%9B%AE%E6%A0%87%E4%B9%8B%EF%BC%9A%E5%8A%A0%E8%BD%BD"><span class="toc-text">性能指标和优化目标之：加载</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%89%93%E5%BC%80%E7%BD%91%E7%AB%99%E7%9A%84%E5%88%9D%E4%BD%93%E9%AA%8C"><span class="toc-text">打开网站的初体验</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BF%9D%E5%AD%98%E5%BF%AB%E7%85%A7"><span class="toc-text">保存快照</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%80%91%E5%B8%83%E5%9B%BE-Waterfall"><span class="toc-text">瀑布图 Waterfall</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%80%A7%E8%83%BD%E6%8C%87%E6%A0%87%E5%92%8C%E4%BC%98%E5%8C%96%E7%9B%AE%E6%A0%87%E4%B9%8B%EF%BC%9A%E4%BA%A4%E4%BA%92"><span class="toc-text">性能指标和优化目标之：交互</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#FPS%E5%B8%A7%E7%8E%87%E3%80%81FRS"><span class="toc-text">FPS帧率、FRS</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%94%A8-RAIL-%E6%A8%A1%E5%9E%8B%E6%B5%8B%E9%87%8F%E6%80%A7%E8%83%BD"><span class="toc-text">用 RAIL 模型测量性能</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1%E3%80%81%E5%93%8D%E5%BA%94"><span class="toc-text">1、响应</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2%E3%80%81%E5%8A%A8%E7%94%BB"><span class="toc-text">2、动画</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3%E3%80%81%E7%A9%BA%E9%97%B2%E6%97%B6%E9%97%B4"><span class="toc-text">3、空闲时间</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4%E3%80%81%E5%8A%A0%E8%BD%BD"><span class="toc-text">4、加载</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8Chrome-DevTools-%E5%88%86%E6%9E%90%E6%80%A7%E8%83%BD"><span class="toc-text">使用Chrome DevTools 分析性能</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#size%EF%BC%9A%E6%96%87%E4%BB%B6%E5%A4%A7%E5%B0%8F%E5%88%86%E6%9E%90"><span class="toc-text">size：文件大小分析</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#performance%EF%BC%9A%E6%80%A7%E8%83%BD%E8%A1%A8%E7%8E%B0"><span class="toc-text">performance：性能表现</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Diable-cache"><span class="toc-text">Diable cache</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%A8%A1%E6%8B%9F%E7%BD%91%E7%BB%9C%E6%83%85%E5%86%B5"><span class="toc-text">模拟网络情况</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Performance-monitor"><span class="toc-text">Performance monitor</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%BF%AB%E6%8D%B7%E9%94%AEESC"><span class="toc-text">快捷键ESC</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8LightHouse%E5%88%86%E6%9E%90%E6%80%A7%E8%83%BD"><span class="toc-text">使用LightHouse分析性能</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Lighthouse-%E4%BB%8B%E7%BB%8D"><span class="toc-text">Lighthouse 介绍</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%BE%E4%BE%8B%EF%BC%9A%E7%A1%AE%E8%AE%A4%E6%9F%90%E4%B8%AAJS-%E6%98%AF%E5%90%A6%E5%BF%85%E9%A1%BB%E5%9C%A8%E9%A6%96%E5%B1%8F%E5%8A%A0%E8%BD%BD"><span class="toc-text">举例：确认某个JS 是否必须在首屏加载</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%80%9A%E8%BF%87npm%E8%BF%90%E8%A1%8C-Lighthouse%E5%B7%A5%E5%85%B7"><span class="toc-text">通过npm运行 Lighthouse工具</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8-WebPageTest-%E8%AF%84%E4%BC%B0%E7%BD%91%E7%AB%99%E6%80%A7%E8%83%BD"><span class="toc-text">使用 WebPageTest 评估网站性能</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#WebPageTest-%E4%BD%BF%E7%94%A8"><span class="toc-text">WebPageTest 使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#WebPageTest-%E6%8A%A5%E5%91%8A%E5%88%86%E6%9E%90"><span class="toc-text">WebPageTest 报告分析</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B1%80%E5%9F%9F%E7%BD%91%E9%83%A8%E7%BD%B2-WebPageTest-%E5%B7%A5%E5%85%B7"><span class="toc-text">局域网部署 WebPageTest 工具</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#chrome%E6%8F%92%E4%BB%B6%EF%BC%9APageSpeed-Insights"><span class="toc-text">chrome插件：PageSpeed Insights</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AE%9E%E6%97%B6%E5%8A%A8%E6%80%81%E6%B5%8B%E9%87%8F%E6%80%A7%E8%83%BD%E7%9A%84API"><span class="toc-text">实时动态测量性能的API</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#performance%EF%BC%9A%E8%8E%B7%E5%8F%96%E5%B8%B8%E8%A7%81%E6%80%A7%E8%83%BD%E5%8F%82%E6%95%B0"><span class="toc-text">performance：获取常见性能参数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%A7%82%E5%AF%9F%E9%95%BF%E4%BB%BB%E5%8A%A1"><span class="toc-text">观察长任务</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%A1%B5%E9%9D%A2%E5%8F%AF%E8%A7%81%E6%80%A7%E7%9A%84%E7%8A%B6%E6%80%81%E7%9B%91%E5%90%AC"><span class="toc-text">页面可见性的状态监听</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BD%91%E7%BB%9C%E7%8A%B6%E5%86%B5%E7%9B%91%E5%90%AC"><span class="toc-text">网络状况监听</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%A3%80%E6%B5%8B%E5%85%83%E7%B4%A0%E7%9A%84%E5%8F%AF%E8%A7%81%E7%8A%B6%E6%80%81%EF%BC%8C%E5%81%9A%E6%9B%9D%E5%85%89%E5%9F%8B%E7%82%B9"><span class="toc-text">检测元素的可见状态，做曝光埋点</span></a></li></ol></li></ol>
      </div>
    </article>
  
  
  <article class="card card-content categories-widget">
    <div class="categories-card">
  <div class="categories-header">
    <i 
      class="iconfont icon-fenlei" 
      style="padding-right: 2px;">
    </i>分类
  </div>
  <div class="categories-list">
    
      <a href="/categories/%E5%89%8D%E7%AB%AF%E5%B7%A5%E5%85%B7/">
        <div class="categories-list-item">
          前端工具
          <span class="categories-list-item-badge">13</span>
        </div>
      </a>
    
      <a href="/categories/CSS%E5%9F%BA%E7%A1%80/">
        <div class="categories-list-item">
          CSS基础
          <span class="categories-list-item-badge">18</span>
        </div>
      </a>
    
      <a href="/categories/CSS%E8%BF%9B%E9%98%B6/">
        <div class="categories-list-item">
          CSS进阶
          <span class="categories-list-item-badge">9</span>
        </div>
      </a>
    
      <a href="/categories/HTML/">
        <div class="categories-list-item">
          HTML
          <span class="categories-list-item-badge">12</span>
        </div>
      </a>
    
      <a href="/categories/JS%E5%9F%BA%E7%A1%80/">
        <div class="categories-list-item">
          JS基础
          <span class="categories-list-item-badge">56</span>
        </div>
      </a>
    
      <a href="/categories/JS%E5%9F%BA%E7%A1%80ES6/">
        <div class="categories-list-item">
          JS基础ES6
          <span class="categories-list-item-badge">10</span>
        </div>
      </a>
    
      <a href="/categories/JS%E5%9F%BA%E7%A1%80%E5%BC%82%E6%AD%A5/">
        <div class="categories-list-item">
          JS基础异步
          <span class="categories-list-item-badge">11</span>
        </div>
      </a>
    
      <a href="/categories/JS%E8%BF%9B%E9%98%B6/">
        <div class="categories-list-item">
          JS进阶
          <span class="categories-list-item-badge">11</span>
        </div>
      </a>
    
      <a href="/categories/%E7%A7%BB%E5%8A%A8web/">
        <div class="categories-list-item">
          移动web
          <span class="categories-list-item-badge">3</span>
        </div>
      </a>
    
      <a href="/categories/CSS%E5%92%8CDOM/">
        <div class="categories-list-item">
          CSS和DOM
          <span class="categories-list-item-badge">6</span>
        </div>
      </a>
    
      <a href="/categories/Node/">
        <div class="categories-list-item">
          Node
          <span class="categories-list-item-badge">16</span>
        </div>
      </a>
    
      <a href="/categories/Vue%E5%9F%BA%E7%A1%80/">
        <div class="categories-list-item">
          Vue基础
          <span class="categories-list-item-badge">15</span>
        </div>
      </a>
    
      <a href="/categories/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/">
        <div class="categories-list-item">
          性能优化
          <span class="categories-list-item-badge">7</span>
        </div>
      </a>
    
      <a href="/categories/%E5%89%8D%E7%AB%AF%E5%B7%A5%E7%A8%8B%E5%8C%96/">
        <div class="categories-list-item">
          前端工程化
          <span class="categories-list-item-badge">8</span>
        </div>
      </a>
    
  </div>
</div>
  </article>
  
  <article class="card card-content tags-widget">
    <div class="tags-card">
  <div class="tags-header">
    <i 
      class="iconfont icon-biaoqian" 
      style="padding-right: 2px;">
    </i>热门标签
  </div>
  <div class="tags-list">
    
      <a 
        href="/tags/JS%E5%9F%BA%E7%A1%80/" 
        title="JS基础">
        <div class="tags-list-item">JS基础</div>
      </a>
    
      <a 
        href="/tags/CSS%E5%9F%BA%E7%A1%80/" 
        title="CSS基础">
        <div class="tags-list-item">CSS基础</div>
      </a>
    
      <a 
        href="/tags/Node/" 
        title="Node">
        <div class="tags-list-item">Node</div>
      </a>
    
      <a 
        href="/tags/Vue%E5%9F%BA%E7%A1%80/" 
        title="Vue基础">
        <div class="tags-list-item">Vue基础</div>
      </a>
    
      <a 
        href="/tags/%E5%89%8D%E7%AB%AF%E5%B7%A5%E5%85%B7/" 
        title="前端工具">
        <div class="tags-list-item">前端工具</div>
      </a>
    
      <a 
        href="/tags/HTML/" 
        title="HTML">
        <div class="tags-list-item">HTML</div>
      </a>
    
      <a 
        href="/tags/JS%E8%BF%9B%E9%98%B6/" 
        title="JS进阶">
        <div class="tags-list-item">JS进阶</div>
      </a>
    
      <a 
        href="/tags/JS%E5%9F%BA%E7%A1%80%E5%BC%82%E6%AD%A5/" 
        title="JS基础异步">
        <div class="tags-list-item">JS基础异步</div>
      </a>
    
      <a 
        href="/tags/JS%E5%9F%BA%E7%A1%80ES6/" 
        title="JS基础ES6">
        <div class="tags-list-item">JS基础ES6</div>
      </a>
    
      <a 
        href="/tags/CSS%E8%BF%9B%E9%98%B6/" 
        title="CSS进阶">
        <div class="tags-list-item">CSS进阶</div>
      </a>
    
      <a 
        href="/tags/%E5%89%8D%E7%AB%AF%E5%B7%A5%E7%A8%8B%E5%8C%96/" 
        title="前端工程化">
        <div class="tags-list-item">前端工程化</div>
      </a>
    
      <a 
        href="/tags/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/" 
        title="性能优化">
        <div class="tags-list-item">性能优化</div>
      </a>
    
      <a 
        href="/tags/CSS%E5%92%8CDOM/" 
        title="CSS和DOM">
        <div class="tags-list-item">CSS和DOM</div>
      </a>
    
      <a 
        href="/tags/%E7%A7%BB%E5%8A%A8web/" 
        title="移动web">
        <div class="tags-list-item">移动web</div>
      </a>
    
  </div>
</div>
  </article>
  
  
</div>
            </aside>
            <main class="main-column">
              
<article class="card card-content">
  <header>
    <h1 class="post-title">
      01-前端性能分析工具和指标
    </h1>
  </header>
  <div class="post-meta post-show-meta">
    <time datetime="2014-07-31T16:00:00.000Z">
      <i 
        class="iconfont icon-calendar" 
        style="margin-right: 2px;">
      </i>
      <span>2014-08-01</span>
    </time>
    
      <span class="dot"></span>
      
        <a 
          href="/categories/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/" 
          class="post-meta-link">
          性能优化
        </a>
      
    
    
      <span class="dot"></span>
      <span>5.7k 字</span>
    
  </div>
  
    <div 
      class="post-meta post-show-meta" 
      style="margin-top: -10px;">
      <div style="display: flex; align-items: center;">
        <i 
          class="iconfont icon-biaoqian" 
          style="margin-right: 2px; font-size: 1.15rem;">
        </i>
        
          
          <a 
            href="/tags/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/" 
            class="post-meta-link">
            性能优化
          </a>
        
      </div>
    </div>
  
  </header>
  <div 
    id="section" 
    class="post-content">
    <p><ArticleTopAd></ArticleTopAd></p>
<h2 id="性能指标和优化目标之：加载"><a href="#性能指标和优化目标之：加载" class="headerlink" title="性能指标和优化目标之：加载"></a>性能指标和优化目标之：加载</h2><p>性能指标：我们在性能优化过程中可以参考的标准。这些标准都是业界或者前人总结出来的指导性经验。我们可以参考这些指标，去指导我们自己的优化。</p>
<h3 id="打开网站的初体验"><a href="#打开网站的初体验" class="headerlink" title="打开网站的初体验"></a>打开网站的初体验</h3><p>我们以淘宝网站为例，按下F12打开浏览器的调试模式。</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210115_1601.png" class="lozad post-image"src="http://img.smyhvae.com/20210115_1601.png"></p>
<p>上图中，鼠标右键点击“刷新”图标（或者鼠标长按刷新图标，松开鼠标后），会弹出三个选项，我们选择最后一个选项“清空缓存并硬性重新加载”。</p>
<p>补充：这三个选项都是在调试模式下（按下F12弹出调试面板）才会出现的。</p>
<p>浏览器的DevTools初印象：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://img.smyhvae.com/20210115_1617.png" class="lozad post-image"src="https://img.smyhvae.com/20210115_1617.png"></p>
<p>上图中，打开 chrome 调试工具，点开「设置」icon，下面的四个选项中，除了“Group by frame”之外，其他的三个选项都可以勾选上。</p>
<p>我们可以看到淘宝网站的一些指标：</p>
<ul>
<li>总资源量是 1.3M。</li>
<li>DOM加载完成时间（DOMContentLoaded）：511ms。这是一个很关键的指标。</li>
<li>其他资源的总加载时间是 1.05秒。</li>
</ul>
<p>我们再来对比一下京东的：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210116-1357.png" class="lozad post-image"src="http://img.smyhvae.com/20210116-1357.png"></p>
<h3 id="保存快照"><a href="#保存快照" class="headerlink" title="保存快照"></a>保存快照</h3><p>network里的信息挺多，我们可以将其保存下来，留着以后做分析、做对照。</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210115-1723.png" class="lozad post-image"src="http://img.smyhvae.com/20210115-1723.png"></p>
<p>如上图所示，我们可以在 network 的空白处右键，选择“Save all as HAR with content”，将 network 信息保存为 <strong>HAR</strong>文件格式。</p>
<p><strong>HAR是一种标准的Web格式，用户保存性能测试的结果。里面的数据是json格式。</strong></p>
<p>我们可以使用第三方的 HAR 分析软件来打开 HAR 文件，比如：</p>
<ul>
<li><p><a target="_blank" rel="noopener" href="https://toolbox.googleapps.com/apps/har_analyzer/?lang=zh-CN">Google 提供的 HAR 分析器</a></p>
</li>
<li><p>Fiddler 抓包工具</p>
</li>
</ul>
<p>注意，HAR 文件包含了一些敏感信息：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210115-1733.png" class="lozad post-image"src="http://img.smyhvae.com/20210115-1733.png"></p>
<h3 id="瀑布图-Waterfall"><a href="#瀑布图-Waterfall" class="headerlink" title="瀑布图 Waterfall"></a>瀑布图 Waterfall</h3><p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210115_1618.png" class="lozad post-image"src="http://img.smyhvae.com/20210115_1618.png"></p>
<p>瀑布图可以非常直观地把网站的加载过程，用自上而下的方式表达出来，就像瀑布一样。</p>
<p>瀑布图有两中解读方式：一种是横向看，一种是纵向看。</p>
<p><strong>1、横向看</strong>：</p>
<p>横向看的是具体的资源，每一行代表某个资源的加载信息。里面有一些色块来表达加载的过程，每个块的颜色不同。也就是说资源的下载不是单一的过程，而是经历了很多环节。</p>
<p>为了了解资源的具体加载过程，我们把鼠标悬浮在第一个资源的色块上，可以看见一个详情列表：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210115_1632.png" class="lozad post-image"src="http://img.smyhvae.com/20210115_1632.png"></p>
<p>（1）等待：</p>
<ul>
<li>Queueing：排队。浏览器会对资源的请求做优先级排序。</li>
</ul>
<p>（2）连接：</p>
<ul>
<li><p>DNS Lookup：DNS域名解析。每个资源都有域名，对域名做DNS解析，然后找到对应服务器的IP地址。</p>
</li>
<li><p>initial connection：客户端和服务器之间建立TCP连接。</p>
</li>
<li><p>SSL证书：该网站为了保证安全性，使用了 https 协议，启用了SSL证书。启用之后，需要做安全认证（SSL协商），这个过程也会耗时。到这里位置，我们可以看到，在请求资源之前，有很多的前置步骤。</p>
</li>
</ul>
<p>（3）请求和响应：</p>
<ul>
<li><p>Request sent：到这一步，真正开始请求资源。</p>
</li>
<li><p>Waiting（<strong>TTFB</strong>）：资源从请求到响应，有一个等待的时间。</p>
</li>
<li><p>Content Download：收到响应后，资源的下载时间。如果值越大，表明下载时间越长。有些同步加载的资源会造成阻塞，导致网页的整体加载时间过长，让用户等待太久。</p>
</li>
</ul>
<p><strong>TTFB</strong> 是一个很重要的指标，它表示的是：请求发出到响应，到底要经历多久。TTFB 可以给我们一个很直观的感受，我们网站的请求和响应到底是快还是慢，很大程度上是由 TTFB 决定。</p>
<p>影响 TTFB 的因素是什么呢？比如：</p>
<ul>
<li><p>后台的处理能力的响应速度。</p>
</li>
<li><p>网络状况：是否有网络延迟。</p>
</li>
</ul>
<p><strong>2、纵向看</strong>：（主要看两点）</p>
<p>（1）看资源与资源之间的联系：如果发生阻塞，说明资源可能是串行地按顺序加载。可以<strong>按需要适当调整为并行</strong>。</p>
<p>（2）看关键的时间节点。Waterfall 中有<strong>两根时间线</strong>：蓝色的线是 DOM 加载完成的时间，红色的线是所有资源加载完成的时间。</p>
<h2 id="性能指标和优化目标之：交互"><a href="#性能指标和优化目标之：交互" class="headerlink" title="性能指标和优化目标之：交互"></a>性能指标和优化目标之：交互</h2><p>上面的内容讲的是<strong>加载</strong>的性能，还有一个需要关注的性能指标是<strong>交互</strong>。也就是网站加载完成后，用户真正开始使用这个网站过程中的的交互体验。</p>
<p>关于交互体验的性能，我们需要关注的是：</p>
<ul>
<li><p>交互动作的<strong>响应时间</strong>要短：比如点击按钮后的弹窗、在搜索框里输入关键字后的搜索结果。</p>
</li>
<li><p>页面滚动要流畅：可以查看 FPS 帧率。</p>
</li>
<li><p>异步请求接口的完成时间要短：比如关注&#x2F;取关主播的响应、领取红包的操作。</p>
</li>
</ul>
<h3 id="FPS帧率、FRS"><a href="#FPS帧率、FRS" class="headerlink" title="FPS帧率、FRS"></a>FPS帧率、FRS</h3><p>这里首先科普两个概念：</p>
<ul>
<li>刷新率：显示器每秒有多少帧画面。大多数显示器的刷新率是60帧&#x2F;秒（即60hz）。</li>
<li>帧率（FPS：frames per second）：视频或者动画的内容本身，每秒有多少帧。由显卡输出帧率。</li>
</ul>
<p>上面的两个参数中，不要把「刷新率」和「帧率」弄混了。「刷新率」是屏幕的参数，「帧率」是图像、视频等内容的参数。人眼最终看到的效果，是以最低的参数为准的。</p>
<p>目前，市场主流手机和电脑屏幕的刷新率基本都是60Hz，即每秒显示60帧画面。也就是说，当我们在使用手机的时候，本质上是手机在连续播放一张张静态图片，每秒播放60张，让肉眼误认为眼前的画面在动。</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210107_2115.gif" class="lozad post-image"src="http://img.smyhvae.com/20210107_2115.gif"></p>
<p>持续滑动的过程中，如果页面输出到显示器的帧率低于60帧&#x2F;秒，则人眼会感觉卡顿。</p>
<p>那么，在浏览器中如何实时显示内容的 FPS 参数呢？打开浏览器的控制台后，按住快捷键「Cmd + Shift + P」，然后输入 <code>frame</code>，选择<code>Show frames per second（FPS） meter</code>。如下：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210115-1930.png" class="lozad post-image"src="http://img.smyhvae.com/20210115-1930.png"></p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210115-2146.png" class="lozad post-image"src="http://img.smyhvae.com/20210115-2146.png"></p>
<p><strong>温馨提示</strong>：</p>
<p>从 2020年7月起，chrome 官方已经取消了 fps参数的显示，改为了 <a target="_blank" rel="noopener" href="https://twitter.com/addyosmani/status/1281483292026400768">FRS</a>：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210115-2006.png" class="lozad post-image"src="http://img.smyhvae.com/20210115-2006.png"></p>
<p>FRS参数观察的是丢帧率：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210115-2010.png" class="lozad post-image"src="http://img.smyhvae.com/20210115-2010.png"></p>
<p>Chrome官方给我们提供了下面这个网站，用于观察 FPS 效果：</p>
<ul>
<li><a target="_blank" rel="noopener" href="http://googlesamples.github.io/web-fundamentals/tools/chrome-devtools/rendering-tools/forcedsync.html">http://googlesamples.github.io/web-fundamentals/tools/chrome-devtools/rendering-tools/forcedsync.html</a></li>
</ul>
<p>如果实在想要看fps，我们可以借助第三方的 <a href="">chrome 插件</a>来查看 fps参数。</p>
<h2 id="用-RAIL-模型测量性能"><a href="#用-RAIL-模型测量性能" class="headerlink" title="用 RAIL 模型测量性能"></a>用 RAIL 模型测量性能</h2><p>RAIL 模型是Google提出的可以量化性能的测量<strong>标准</strong>。我们做性能优化时，要尽可能到这个标准。</p>
<p>在做性能优化的时候，我们需要有人告诉我们：做到多好才算好？有没有一些通用的标准？而 RAIL 模型 可以给我们带来量化的指标。</p>
<p><strong>RAIL 模型包括四个方面</strong>：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210115-2027.png" class="lozad post-image"src="http://img.smyhvae.com/20210115-2027.png"></p>
<ul>
<li><p>Response：响应</p>
</li>
<li><p>Animation：动画</p>
</li>
<li><p>Idle：空闲时间</p>
</li>
<li><p>load：加载</p>
</li>
</ul>
<p>参考链接：</p>
<ul>
<li><p><a target="_blank" rel="noopener" href="https://juejin.cn/post/6872474167543857165">[Web翻译]用RAIL模型测量性能</a></p>
</li>
<li><p><a target="_blank" rel="noopener" href="https://web.dev/rail/">https://web.dev/rail/</a></p>
</li>
</ul>
<p><strong>RAIL 的目标</strong>：</p>
<ul>
<li>让良好的用户体验成为性能优化的目标</li>
</ul>
<p>接下来，我们再看看看 RAIL 的评估标准。</p>
<h3 id="1、响应"><a href="#1、响应" class="headerlink" title="1、响应"></a>1、响应</h3><p><strong>目标</strong>：处理用户发起的响应，应该在 50ms 内完成。</p>
<p><strong>准则</strong>：</p>
<ul>
<li><p>在50毫秒内处理用户输入事件。这适用于大多数输入，如点击按钮、切换表单控件或启动动画。这不适用于触摸拖动或滚动。</p>
</li>
<li><p>对于需要超过50毫秒才能完成的操作，需要提供反馈。</p>
</li>
</ul>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210115-2039.png" class="lozad post-image"src="http://img.smyhvae.com/20210115-2039.png"></p>
<p>如上图所示，Google经过大量研究发现，用户能够接受的最高延时是100ms。所以，从用户发起交互请求（输入任务）后，前端最好能在100ms内给出反馈。</p>
<p><strong>但是我们的预算只有50毫秒</strong>。因为应用程序在接收到输入任务的时候，不一定会马上着手处理，它可能还有其他工作正在进行，这意味着当前的输入任务可能需要排队50ms左右。所以我们真正能处理这个请求的时间，并没有100ms。</p>
<h3 id="2、动画"><a href="#2、动画" class="headerlink" title="2、动画"></a>2、动画</h3><p><strong>目标</strong>：在10毫秒或更短的时间内制作出动画中的每一帧。（即：100帧&#x2F;秒。）</p>
<p>我们知道，当动画的帧率是 &gt;&#x3D; 60帧&#x2F;秒 的时候，人眼才不会觉得卡顿。此时的理论值为 1000毫秒&#x2F;60帧 &#x3D; 16.6 毫秒&#x2F;帧。</p>
<p>10毫秒和16毫秒之间，隔了6秒。这6秒是什么呢？因为浏览器需要大约6毫秒的时间来渲染每一帧，所以，每一帧的准则建议是10毫秒，而不是 16.6毫秒。</p>
<p>假设动画本身是60帧&#x2F;秒，那么，最终渲染出来的效果可能只有 45帧&#x2F;秒。</p>
<p><strong>广义的动画</strong>：</p>
<p>动画不仅仅是花哨的UI效果。每一种交互都被认为是动画。比如：</p>
<ul>
<li><p>视觉动画</p>
</li>
<li><p>滚动</p>
</li>
<li><p>拖动、平移元素、放大图片等。</p>
</li>
</ul>
<h3 id="3、空闲时间"><a href="#3、空闲时间" class="headerlink" title="3、空闲时间"></a>3、空闲时间</h3><p><strong>目标</strong>：最大化闲置时间，增加页面在50毫秒内响应用户输入的几率。</p>
<p>这个空闲时间，是和上面的第一点“响应”是结合在一起的。只有空闲足够多，当用户的交互来的时候，我们才能有足够的时间进行处理。</p>
<p><strong>准则</strong>：</p>
<ul>
<li><p>利用空闲时间做延迟加载。例如，页面在初始化的时候，尽可能少的加载数据，然后利用空闲时间加载其余部分。</p>
</li>
<li><p>在空闲时间内处理任务，时间不能超过50毫秒。否则，就阻塞了用户做其他的输入请求，导致卡顿。</p>
</li>
<li><p>如果用户在闲置时间工作期间与页面进行交互，那么这个交互应始终处于最高优先级，并中断闲置时间工作。</p>
</li>
</ul>
<h3 id="4、加载"><a href="#4、加载" class="headerlink" title="4、加载"></a>4、加载</h3><p><strong>目标</strong>：在5秒或更短的时间内加载页面并可以交互。</p>
<p><strong>准则</strong>：</p>
<ul>
<li><p>这里的5秒包括：加载、解析、渲染，并确保用户可以交互。</p>
</li>
<li><p>加载的过程中，可以使用loading框、进度条、骨架屏等方式缓解用户焦虑。</p>
</li>
</ul>
<h2 id="使用Chrome-DevTools-分析性能"><a href="#使用Chrome-DevTools-分析性能" class="headerlink" title="使用Chrome DevTools 分析性能"></a>使用Chrome DevTools 分析性能</h2><p>现在主流的性能测量工具：</p>
<ul>
<li><p>Chrome DevTools：开发调试、分析性能。</p>
</li>
<li><p>Lighthouse 网站整体质量评估。</p>
</li>
<li><p>WebPageTest：给网站提供多个地点的测试，以及全面的性能报告。</p>
</li>
</ul>
<p>这一段，我们先来讲一讲 Chrome DevTools 。</p>
<p>大家平时在用 Chrome DevTools 的时候，一般使用来开发调试、查看 DOM、css、接口请求等，但其实，这个工具非常强大。</p>
<h3 id="size：文件大小分析"><a href="#size：文件大小分析" class="headerlink" title="size：文件大小分析"></a>size：文件大小分析</h3><p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210116-0946.png" class="lozad post-image"src="http://img.smyhvae.com/20210116-0946.png"></p>
<p>可以把size从到小排序，看看哪个资源的文件较大。</p>
<p>另外，上图中的横线处说明：该文件在网络传输的时候会做压缩（125kb），拿到资源之后再解压还原（526kb）。</p>
<h3 id="performance：性能表现"><a href="#performance：性能表现" class="headerlink" title="performance：性能表现"></a>performance：性能表现</h3><p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210116-0959.png" class="lozad post-image"src="http://img.smyhvae.com/20210116-0959.png"></p>
<p>preformance的两个作用：</p>
<ul>
<li>Record button：记录页面加载、用户交互等全过程，直到我们手动点击停止按钮。</li>
<li>Reload button：记录页面从刷新到资源加载完成的过程。会自动停止记录。</li>
</ul>
<p>参数解读：</p>
<ul>
<li><p>Timing：关键的时间节点。</p>
</li>
<li><p>Main：主线程做了哪些任务，以及调用关系。</p>
</li>
</ul>
<p>Timing参数中，尤其注意看<code>DCL</code>（DOMContentLoaded），即DOM加载完成的时间节点。我们可以通过<code>Main</code>参数看看DOM在加载完成之前，都做了些什么事情。很有可能就是这些事情导致 <code>DCL</code>的时间过晚。</p>
<p>我们可以翻到<code>Main</code>里的最后一行（即最终调用的位置），往往这个位置就是我们自己写的代码。</p>
<h3 id="Diable-cache"><a href="#Diable-cache" class="headerlink" title="Diable cache"></a>Diable cache</h3><p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210116-1014.png" class="lozad post-image"src="http://img.smyhvae.com/20210116-1014.png"></p>
<p>上图中的<code>Diable cache</code>是一个很重要的设置选项。</p>
<p>勾选<code>Diable cache</code>：</p>
<ul>
<li>不走缓存，相当于页面初次访问。</li>
<li>如果你希望改的代码立即生效，就一定要勾选上。</li>
</ul>
<p>不勾选<code>Diable cache</code>：</p>
<ul>
<li>走缓存，相当于页面二次、三次访问。</li>
<li>很多时候，我们需要关心用户在第二次、第三次访问时候，他的访问速度如何、性能如何、我们设置的缓存有没有生效。此时就不要勾选上。</li>
</ul>
<h3 id="模拟网络情况"><a href="#模拟网络情况" class="headerlink" title="模拟网络情况"></a>模拟网络情况</h3><p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210116-1023.png" class="lozad post-image"src="http://img.smyhvae.com/20210116-1023.png"></p>
<p>模拟网络状况（自定义参数）：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210116-1026.png" class="lozad post-image"src="http://img.smyhvae.com/20210116-1026.png"></p>
<h3 id="Performance-monitor"><a href="#Performance-monitor" class="headerlink" title="Performance monitor"></a>Performance monitor</h3><p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210116-1032.png" class="lozad post-image"src="http://img.smyhvae.com/20210116-1032.png"></p>
<h3 id="快捷键ESC"><a href="#快捷键ESC" class="headerlink" title="快捷键ESC"></a>快捷键ESC</h3><p>按住快捷键ESC，会列出其他常用的功能菜单：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210116-1028.png" class="lozad post-image"src="http://img.smyhvae.com/20210116-1028.png"></p>
<h2 id="使用LightHouse分析性能"><a href="#使用LightHouse分析性能" class="headerlink" title="使用LightHouse分析性能"></a>使用LightHouse分析性能</h2><p>我们之所以使用不同的性能测量工具，是因为他们都有不同的特点。这一段要讲的 lighthouse 既可以帮我们生成简易的测试报告，还可以给出一些针对性的优化建议。后面要讲的 WebPageTest 可以帮我们生成详细的性能测试报告。</p>
<p>我们先来看看 Lighthouse。</p>
<h3 id="Lighthouse-介绍"><a href="#Lighthouse-介绍" class="headerlink" title="Lighthouse 介绍"></a>Lighthouse 介绍</h3><p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210115-1739.png" class="lozad post-image"src="http://img.smyhvae.com/20210115-1739.png"></p>
<p>lighthouse 是 chrome 浏览器的一个性能测量工具。我们先来看看它的性能指标，至于它具体使用，后续的内容再详细介绍。</p>
<p>淘宝跑分举例：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210115-1758.png" class="lozad post-image"src="http://img.smyhvae.com/20210115-1758.png"></p>
<p>京东跑分举例：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210115-1759.png" class="lozad post-image"src="http://img.smyhvae.com/20210115-1759.png"></p>
<p>Lighthouse 跑分里，最重要的两个指标如下：</p>
<ul>
<li><p><strong>First Contentful Paint（白屏时间）</strong>：<strong>从白屏到第一次出现内容的时间。</strong>我们可以看到，上面提供了一些加载过程的截图，10屏里如果只有1到2屏是白屏，说明体验还是可以的。</p>
</li>
<li><p><strong>Speed Index</strong>：速度指数。</p>
</li>
</ul>
<p>我们不需要关心这个指数是怎么来的，因为背后涉及一套很复杂的公式，我们暂时只需关注这个数值。</p>
<p>Speed Index 标准为4秒（超过4秒算比较慢的），我们测的淘宝的 speed index 是0.5s，很快了。但我们要结合网站本身的业务来<strong>权衡</strong>。并不是分数越高性能越高，比如百度这样的网站，页面上的内容很少，测出来的分数肯定很完美。而淘宝需要展示很多内容给用户看。所以，这个指标只是一个指导作用，并不一定能够达到最优的数值。</p>
<p>Lighthouse 的分析结果里，也给出了颜色标注：</p>
<ul>
<li>红色：比较严重的性能问题</li>
<li>黄色：需要做适当优化</li>
<li>绿色：说明性能表现很好。</li>
</ul>
<p>另外，Lighthouse  还会给出一些优化建议：</p>
<ul>
<li><p>Opportunities:优化建议。</p>
</li>
<li><p>Diagnostics：问题诊断。</p>
</li>
<li><p>Passed audits：表示这部分没有问题。</p>
</li>
</ul>
<h3 id="举例：确认某个JS-是否必须在首屏加载"><a href="#举例：确认某个JS-是否必须在首屏加载" class="headerlink" title="举例：确认某个JS 是否必须在首屏加载"></a>举例：确认某个JS 是否必须在首屏加载</h3><p>就拿B站来举例，来看看它的lighthouse报告：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210116_0107.png" class="lozad post-image"src="http://img.smyhvae.com/20210116_0107.png"></p>
<p>上图中给出了一个优化建议：有些JS文件不是首屏加载必须的。</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210116_0108.png" class="lozad post-image"src="http://img.smyhvae.com/20210116_0108.png"></p>
<p>我们随便拿一个JS文件来测试（比如上图中，Header标签里的JS文件）。做法如下：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210116-0901.png" class="lozad post-image"src="http://img.smyhvae.com/20210116-0901.png"></p>
<p>如上图所示，在 chrome 控制台输入快捷键「Cmd + Shift + P」，然后输入文本<code>block</code>，选择<code>Show Network request blocking</code>：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210116-0903.png" class="lozad post-image"src="http://img.smyhvae.com/20210116-0903.png"></p>
<p>按照上面的步骤添加规则，点击add后，效果如下：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210116-0904.png" class="lozad post-image"src="http://img.smyhvae.com/20210116-0904.png"></p>
<p>然后，我们切换到控制台的 network面板，并刷新页面：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210116-0905.png" class="lozad post-image"src="http://img.smyhvae.com/20210116-0905.png"></p>
<p>然后观察这个js资源是不是首屏加载所必须的。但我们也不能就此定论说这个资源一定可以延迟加载，也许它就是想让页面在一开始loading的时候就捕获日志。</p>
<p>对于我们自己的网站，这个资源是首屏加载必须的吗？一定要在第一时间加载吗？需要根据特定的业务做衡量。</p>
<h3 id="通过npm运行-Lighthouse工具"><a href="#通过npm运行-Lighthouse工具" class="headerlink" title="通过npm运行 Lighthouse工具"></a>通过npm运行 Lighthouse工具</h3><pre class="highlight"><span class="line"><span class="comment"># 安装</span></span><br><span class="line">npm install -g lighthouse</span><br><span class="line"></span><br><span class="line"><span class="comment"># 执行</span></span><br><span class="line">lighthouse https://www.jd.com</span><br><span class="line"></span><br><span class="line"><span class="comment"># 输出性能检测报告</span></span><br><span class="line">Generating results...</span><br><span class="line">html output witten to /Users/smyh/Documents/wpt-mac-agent/www.jd.com._2021-01-16_09-00-00.html</span><br></pre>






<h2 id="使用-WebPageTest-评估网站性能"><a href="#使用-WebPageTest-评估网站性能" class="headerlink" title="使用 WebPageTest 评估网站性能"></a>使用 WebPageTest 评估网站性能</h2><p>程序员经常说的有句话是：“我这儿能打开啊。我这儿不报错呀。”大家应该都懂这个梗，这就是为什么，我们要借助第三方的测试工具，而不仅仅只是自己电脑上访问正常就ok了。</p>
<p>我们需要借助 WebPageTest 这样的第三方测试工具，去模拟各种用户的真实场景。</p>
<h3 id="WebPageTest-使用"><a href="#WebPageTest-使用" class="headerlink" title="WebPageTest 使用"></a>WebPageTest 使用</h3><p>网址：<a target="_blank" rel="noopener" href="https://www.webpagetest.org/">https://www.webpagetest.org</a></p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210115-2203.png" class="lozad post-image"src="http://img.smyhvae.com/20210115-2203.png"></p>
<p>WebPageTest 在世界各地提供了非常多的服务器，在每个服务器上部署了不同的浏览器，可以让我们有针对性的做测试。如果你做的是一款国际化网站，那更有必要使用一下了。</p>
<p>我们以JD网站举例：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210115-2225.png" class="lozad post-image"src="http://img.smyhvae.com/20210115-2225.png"></p>
<p>按照上面的选项配置完成后，点击右侧的「Start Test」即可开始测试。然后等待：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210115-2226.png" class="lozad post-image"src="http://img.smyhvae.com/20210115-2226.png"></p>
<h3 id="WebPageTest-报告分析"><a href="#WebPageTest-报告分析" class="headerlink" title="WebPageTest 报告分析"></a>WebPageTest 报告分析</h3><p>淘宝网站性能测试报告：</p>
<ul>
<li><p>2020年6月：<a target="_blank" rel="noopener" href="https://webpagetest.org/result/200616_JK_78eebda338285ffe0c2e154ca5032839/">https://webpagetest.org/result/200616_JK_78eebda338285ffe0c2e154ca5032839/</a></p>
</li>
<li><p>2021年1月：<a target="_blank" rel="noopener" href="https://www.webpagetest.org/result/210115_DiCB_f1344d732760365151755e89765b2d37/">https://www.webpagetest.org/result/210115_DiCB_f1344d732760365151755e89765b2d37/</a></p>
</li>
</ul>
<p>JD网站性能测试报告：</p>
<ul>
<li>2021年1月：<a target="_blank" rel="noopener" href="https://www.webpagetest.org/result/210115_DiGT_8d7370e91230b7d077e40b7aafb485a5/">https://www.webpagetest.org/result/210115_DiGT_8d7370e91230b7d077e40b7aafb485a5/</a></li>
</ul>
<p>拿到 WebPageTest 报告之后，我们来看看报告里的几个重点指标。</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210116_1314.png" class="lozad post-image"src="http://img.smyhvae.com/20210116_1314.png"></p>
<p>1、摘要里的参数：（如上图）</p>
<ul>
<li>First Byte：第一个请求的响应时间。可以反映后台的处理能力，以及网络回路的情况。</li>
<li>Start Render：从白屏到首次渲染的时间。</li>
<li>Speed Index：速度指数。</li>
<li><strong>Total Blocking Time</strong>：页面被阻塞，导致用户不能交互的累计时间。</li>
</ul>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210116_1315.png" class="lozad post-image"src="http://img.smyhvae.com/20210116_1315.png"></p>
<p>2、详情里的参数：<strong>First View</strong>。</p>
<p>First View展示的是：首次访问时，总的加载时间。这里面提供的瀑布图，比 chrome DevTools里提供的更为详细。</p>
<p>点击进入 First View 的详情之后，可以看到：所有的资源请求，都会在这里列出来。如下：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210116_1316.png" class="lozad post-image"src="http://img.smyhvae.com/20210116_1316.png"></p>
<ul>
<li>page is Interactive：页面在加载的过程中，大部分时间段，用户都是可以交互的。这是非常有用的一个指标。</li>
<li>Brower Main thread：浏览器主线程的占用情况。可以看看空闲的时间多不多。</li>
<li>CPU Utilization：CPU的使用情况。</li>
<li>多张图片的资源请求。</li>
</ul>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210116_1317.png" class="lozad post-image"src="http://img.smyhvae.com/20210116_1317.png"></p>
<p>上图中，我们可以看到：多张图片的开始请求时间都是相同的。也就是说，如果让资源做<strong>并行加载</strong>，我们就可以加大地减少加载时间，<strong>最终所消耗的时间就由最大的图片来决定</strong>。这是一个很好的优化技巧，至于具体是怎么实现的，可以自行了解。</p>
<p>另外，我们看到，有一部分的请求，被高亮出来了：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210115-2250.png" class="lozad post-image"src="http://img.smyhvae.com/20210115-2250.png"></p>
<p>上面这张图的意思是：302表示重定向，也就是说，这个资源已经不在原来请求的位置了，需要重定向才能找到真实的位置。这个地方其实可以做一个优化：</p>
<blockquote>
<p>不需要去访问之前的无效的资源，可以直接去访问重定向后的那个资源。</p>
</blockquote>
<h3 id="局域网部署-WebPageTest-工具"><a href="#局域网部署-WebPageTest-工具" class="headerlink" title="局域网部署 WebPageTest 工具"></a>局域网部署 WebPageTest 工具</h3><p>如果我们开发的页面，还没有上线，公网则无法访问。这个时候我们也想通过WebPageTest看看网站的性能，那要怎么办呢？</p>
<p>我们可以在局域网部署 WebPageTest 工具，具体方法可自行研究。</p>
<h2 id="chrome插件：PageSpeed-Insights"><a href="#chrome插件：PageSpeed-Insights" class="headerlink" title="chrome插件：PageSpeed Insights"></a>chrome插件：PageSpeed Insights</h2><p>另外，google官方也有一个网址：<a target="_blank" rel="noopener" href="https://developers.google.com/speed/pagespeed/insights/?hl=zh-cn">https://developers.google.com/speed/pagespeed/insights/?hl=zh-cn</a></p>
<p>但是这个网站在使用时，经常挂掉。</p>
<p>这个插件是2018年的，已经好几年没更新了。大家参考即可。</p>
<h2 id="实时动态测量性能的API"><a href="#实时动态测量性能的API" class="headerlink" title="实时动态测量性能的API"></a>实时动态测量性能的API</h2><p>Chrome DevTools能够检测各种性能参数，其实也是调用了一些性能相关的标准API。我们自己也可以直接在代码里调用这些api。</p>
<p>通过 <code>performance</code>对象提供的API，我们可以实时的、精细化、自定义测量性能，获取相应的参数。也可以把这些性能参数，打印到控制台，或者实时上报给后台监控系统。</p>
<h3 id="performance：获取常见性能参数"><a href="#performance：获取常见性能参数" class="headerlink" title="performance：获取常见性能参数"></a>performance：获取常见性能参数</h3><p>常见性能参数，计算公式如下：</p>
<blockquote>
<p>时间戳1减去时间戳2，得到的差值，就是我们想要看到的耗时。</p>
</blockquote>
<ul>
<li><p>DNS 解析耗时: domainLookupEnd - domainLookupStart</p>
</li>
<li><p>TCP 连接耗时: connectEnd - connectStart</p>
</li>
<li><p>SSL 安全连接耗时: connectEnd - secureConnectionStart</p>
</li>
<li><p>网络请求耗时 (TTFB): responseStart - requestStart</p>
</li>
<li><p>数据传输耗时: responseEnd - responseStart</p>
</li>
<li><p>DOM 解析耗时: domInteractive - responseEnd</p>
</li>
<li><p>资源加载耗时: loadEventStart - domContentLoadedEventEnd</p>
</li>
<li><p>First Byte时间: responseStart - domainLookupStart</p>
</li>
<li><p>白屏时间: responseEnd - fetchStart</p>
</li>
<li><p>首次可交互时间（<strong>TTI</strong>）: domInteractive - fetchStart</p>
</li>
<li><p>DOM Ready 时间: domContentLoadEventEnd - fetchStart</p>
</li>
<li><p>页面完全加载时间: loadEventStart - fetchStart</p>
</li>
<li><p>http 头部大小： transferSize - encodedBodySize</p>
</li>
<li><p>重定向次数：performance.navigation.redirectCount</p>
</li>
<li><p>重定向耗时: redirectEnd - redirectStart</p>
</li>
</ul>
<p>比如说，如果我们想要获取 TTI参数，代码可以这样写：</p>
<pre class="highlight"><span class="line"><span class="comment">// 计算一些关键的性能指标</span></span><br><span class="line"><span class="variable language_">window</span>.<span class="title function_">addEventListener</span>(<span class="string">&#x27;load&#x27;</span>, <span class="function">(<span class="params">event</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="comment">// Time to Interactive</span></span><br><span class="line">    <span class="keyword">let</span> timing = performance.<span class="title function_">getEntriesByType</span>(<span class="string">&#x27;navigation&#x27;</span>)[<span class="number">0</span>];</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(timing.<span class="property">domInteractive</span>);</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(timing.<span class="property">fetchStart</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">let</span> diff = timing.<span class="property">domInteractive</span> - timing.<span class="property">fetchStart</span>;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;TTI: &quot;</span> + diff); <span class="comment">// 打印 TTI 参数</span></span><br><span class="line">&#125;)</span><br></pre>



<h3 id="观察长任务"><a href="#观察长任务" class="headerlink" title="观察长任务"></a>观察长任务</h3><pre class="highlight"><span class="line"><span class="keyword">const</span> observer = <span class="keyword">new</span> <span class="title class_">PerformanceObserver</span>(<span class="function">(<span class="params">list</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">const</span> entry <span class="keyword">of</span> list.<span class="title function_">getEntries</span>()) &#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(entry)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">observer.<span class="title function_">observe</span>(&#123;<span class="attr">entryTypes</span>: [<span class="string">&#x27;longtask&#x27;</span>]&#125;)</span><br></pre>



<h3 id="页面可见性的状态监听"><a href="#页面可见性的状态监听" class="headerlink" title="页面可见性的状态监听"></a>页面可见性的状态监听</h3><p>使用场景举例：</p>
<ul>
<li>比如说，我们正在做一个视频网站（或者游戏页面）。如果用户当前没有在看这个视频，而是切换别的页面了。此时，我们可以对视频做节流等处理，避免造成性能的浪费。等用户再回到当前页面之后，再恢复之前的状态。</li>
<li>当设备进入待机模式时（用户按下电源键关闭屏幕），网站想要关闭设备声音。</li>
</ul>
<p>针对这种场景，我们可以使用<code>visibilitychange</code>进行监听：</p>
<pre class="highlight"><span class="line"><span class="comment">// 见面可见性的状态监听</span></span><br><span class="line"><span class="keyword">let</span> vEvent = <span class="string">&#x27;visibilitychange&#x27;</span>;</span><br><span class="line"><span class="keyword">if</span> (<span class="variable language_">document</span>.<span class="property">webkitHidden</span> != <span class="literal">undefined</span>) &#123;</span><br><span class="line">    <span class="comment">// webkit prefix detected</span></span><br><span class="line">    vEvent = <span class="string">&#x27;webkitvisibilitychange&#x27;</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">visibilityChanged</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable language_">document</span>.<span class="property">hidden</span> || <span class="variable language_">document</span>.<span class="property">webkitHidden</span>) &#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;Web page is hidden.&quot;</span>)</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;Web page is visible.&quot;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">document</span>.<span class="title function_">addEventListener</span>(vEvent, visibilityChanged, <span class="literal">false</span>);</span><br></pre>



<h3 id="网络状况监听"><a href="#网络状况监听" class="headerlink" title="网络状况监听"></a>网络状况监听</h3><p>使用场景举例：</p>
<ul>
<li>高清图片按需加载：如果用户的网络条件较好，就加载高清图片资源；如果网络条件不好，就加载文件较小的图片资源。</li>
</ul>
<p>代码举例：</p>
<pre class="highlight"><span class="line"><span class="keyword">var</span> connection = navigator.<span class="property">connection</span> || navigator.<span class="property">mozConnection</span> || navigator.<span class="property">webkitConnection</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> type = connection.<span class="property">effectiveType</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">updateConnectionStatus</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="comment">// type是之前的网络状态，connection.effectiveType是当前最新的网络状态</span></span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;Connection type changed from &quot;</span> + type + <span class="string">&quot; to &quot;</span> + connection.<span class="property">effectiveType</span>);</span><br><span class="line"></span><br><span class="line">  type = connection.<span class="property">effectiveType</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">connection.<span class="title function_">addEventListener</span>(<span class="string">&#x27;change&#x27;</span>, updateConnectionStatus);</span><br></pre>

<p>打印结果举例：</p>
<pre class="highlight"><span class="line">Connection type changed from 4g to 3g</span><br></pre>

<h3 id="检测元素的可见状态，做曝光埋点"><a href="#检测元素的可见状态，做曝光埋点" class="headerlink" title="检测元素的可见状态，做曝光埋点"></a>检测元素的可见状态，做曝光埋点</h3><p>我们可以通过<code>IntersectionObserver：</code>这个API来检测元素的可见状态：</p>
<p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="http://img.smyhvae.com/20210117_1635.png" class="lozad post-image"src="http://img.smyhvae.com/20210117_1635.png"></p>
<p>做曝光上报的埋点：判断某个DOM（或者某个楼层）是否出现在视窗中，出现了就收集数据上报给服务端。</p>
<p>本质就是要计算某一元素和另一元素（视窗）的相对位置&#x2F;相对可视状态，然后进行一些操作（一般是上报给服务端）。</p>
<p>参考：</p>
<ul>
<li><a target="_blank" rel="noopener" href="https://cnodejs.org/topic/5e0a0edb0696c446bf650dec">前端埋点之曝光实现</a></li>
<li><a target="_blank" rel="noopener" href="https://github.com/Hugohui/vueTrackSdk">点击埋点和曝光卖点的封装</a></li>
</ul>

  </div>
  <div>
    
      <div 
        class="post-note note-warning copyright" 
        style="margin-top: 42px">
        <p>
          <span style="font-weight: bold;">作者：</span><a 
            target="_blank" 
            rel="nofollow noopener noreferrer" 
            href="/about">
            zwl5670
          </a>
        </p>
        <p>
          <span style="font-weight: bold;">文章链接：</span><a 
            target="_blank" 
            rel="nofollow noopener noreferrer" 
            href="https://zwl5670.gitee.io/2014/08/01/14-%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/01-%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90%E5%B7%A5%E5%85%B7%E5%92%8C%E6%8C%87%E6%A0%87/">
            https://zwl5670.gitee.io/2014/08/01/14-%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/01-%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90%E5%B7%A5%E5%85%B7%E5%92%8C%E6%8C%87%E6%A0%87/
          </a>
        </p>
        <p><span style="font-weight: bold;">版权声明：</span>本博客所有文章除特别声明外，均采用<a target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh">CC BY-NC-SA 4.0 协议</a>。转载请注明出处！</p>
      </div>
    
  </div>
</article>
<div class="nav">
  
    <div class="nav-item-prev">
      <a 
        href="/2014/08/01/14-%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/03-%E6%B8%B2%E6%9F%93%E4%BC%98%E5%8C%96/" 
        class="nav-link">
        <i class="iconfont icon-left nav-prev-icon"></i>
        <div>
          <div class="nav-label">上一篇</div>
          
            <div class="nav-title">03-渲染优化 </div>
          
        </div>
      </a>
    </div>
  
  
    <div class="nav-item-next">
      <a 
        href="/2014/08/01/14-%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/02-%E6%B5%8F%E8%A7%88%E5%99%A8%E6%B8%B2%E6%9F%93%E6%9C%BA%E5%88%B6/" 
        class="nav-link">
        <div>
          <div class="nav-label">下一篇</div>
          
            <div class="nav-title">02-浏览器渲染机制 </div>
          
        </div>
        <i class="iconfont icon-right nav-next-icon"></i>
      </a>
    </div>
  
</div>

<div 
  class="card card-content toc-card" 
  id="mobiletoc">
  <div class="toc-header">
  <i 
    class="iconfont icon-menu" 
    style="padding-right: 2px;">
  </i>目录
</div>
<ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%80%A7%E8%83%BD%E6%8C%87%E6%A0%87%E5%92%8C%E4%BC%98%E5%8C%96%E7%9B%AE%E6%A0%87%E4%B9%8B%EF%BC%9A%E5%8A%A0%E8%BD%BD"><span class="toc-text">性能指标和优化目标之：加载</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%89%93%E5%BC%80%E7%BD%91%E7%AB%99%E7%9A%84%E5%88%9D%E4%BD%93%E9%AA%8C"><span class="toc-text">打开网站的初体验</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BF%9D%E5%AD%98%E5%BF%AB%E7%85%A7"><span class="toc-text">保存快照</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%80%91%E5%B8%83%E5%9B%BE-Waterfall"><span class="toc-text">瀑布图 Waterfall</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%80%A7%E8%83%BD%E6%8C%87%E6%A0%87%E5%92%8C%E4%BC%98%E5%8C%96%E7%9B%AE%E6%A0%87%E4%B9%8B%EF%BC%9A%E4%BA%A4%E4%BA%92"><span class="toc-text">性能指标和优化目标之：交互</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#FPS%E5%B8%A7%E7%8E%87%E3%80%81FRS"><span class="toc-text">FPS帧率、FRS</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%94%A8-RAIL-%E6%A8%A1%E5%9E%8B%E6%B5%8B%E9%87%8F%E6%80%A7%E8%83%BD"><span class="toc-text">用 RAIL 模型测量性能</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1%E3%80%81%E5%93%8D%E5%BA%94"><span class="toc-text">1、响应</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2%E3%80%81%E5%8A%A8%E7%94%BB"><span class="toc-text">2、动画</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3%E3%80%81%E7%A9%BA%E9%97%B2%E6%97%B6%E9%97%B4"><span class="toc-text">3、空闲时间</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4%E3%80%81%E5%8A%A0%E8%BD%BD"><span class="toc-text">4、加载</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8Chrome-DevTools-%E5%88%86%E6%9E%90%E6%80%A7%E8%83%BD"><span class="toc-text">使用Chrome DevTools 分析性能</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#size%EF%BC%9A%E6%96%87%E4%BB%B6%E5%A4%A7%E5%B0%8F%E5%88%86%E6%9E%90"><span class="toc-text">size：文件大小分析</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#performance%EF%BC%9A%E6%80%A7%E8%83%BD%E8%A1%A8%E7%8E%B0"><span class="toc-text">performance：性能表现</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Diable-cache"><span class="toc-text">Diable cache</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%A8%A1%E6%8B%9F%E7%BD%91%E7%BB%9C%E6%83%85%E5%86%B5"><span class="toc-text">模拟网络情况</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Performance-monitor"><span class="toc-text">Performance monitor</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%BF%AB%E6%8D%B7%E9%94%AEESC"><span class="toc-text">快捷键ESC</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8LightHouse%E5%88%86%E6%9E%90%E6%80%A7%E8%83%BD"><span class="toc-text">使用LightHouse分析性能</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Lighthouse-%E4%BB%8B%E7%BB%8D"><span class="toc-text">Lighthouse 介绍</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%BE%E4%BE%8B%EF%BC%9A%E7%A1%AE%E8%AE%A4%E6%9F%90%E4%B8%AAJS-%E6%98%AF%E5%90%A6%E5%BF%85%E9%A1%BB%E5%9C%A8%E9%A6%96%E5%B1%8F%E5%8A%A0%E8%BD%BD"><span class="toc-text">举例：确认某个JS 是否必须在首屏加载</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%80%9A%E8%BF%87npm%E8%BF%90%E8%A1%8C-Lighthouse%E5%B7%A5%E5%85%B7"><span class="toc-text">通过npm运行 Lighthouse工具</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8-WebPageTest-%E8%AF%84%E4%BC%B0%E7%BD%91%E7%AB%99%E6%80%A7%E8%83%BD"><span class="toc-text">使用 WebPageTest 评估网站性能</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#WebPageTest-%E4%BD%BF%E7%94%A8"><span class="toc-text">WebPageTest 使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#WebPageTest-%E6%8A%A5%E5%91%8A%E5%88%86%E6%9E%90"><span class="toc-text">WebPageTest 报告分析</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B1%80%E5%9F%9F%E7%BD%91%E9%83%A8%E7%BD%B2-WebPageTest-%E5%B7%A5%E5%85%B7"><span class="toc-text">局域网部署 WebPageTest 工具</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#chrome%E6%8F%92%E4%BB%B6%EF%BC%9APageSpeed-Insights"><span class="toc-text">chrome插件：PageSpeed Insights</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AE%9E%E6%97%B6%E5%8A%A8%E6%80%81%E6%B5%8B%E9%87%8F%E6%80%A7%E8%83%BD%E7%9A%84API"><span class="toc-text">实时动态测量性能的API</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#performance%EF%BC%9A%E8%8E%B7%E5%8F%96%E5%B8%B8%E8%A7%81%E6%80%A7%E8%83%BD%E5%8F%82%E6%95%B0"><span class="toc-text">performance：获取常见性能参数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%A7%82%E5%AF%9F%E9%95%BF%E4%BB%BB%E5%8A%A1"><span class="toc-text">观察长任务</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%A1%B5%E9%9D%A2%E5%8F%AF%E8%A7%81%E6%80%A7%E7%9A%84%E7%8A%B6%E6%80%81%E7%9B%91%E5%90%AC"><span class="toc-text">页面可见性的状态监听</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BD%91%E7%BB%9C%E7%8A%B6%E5%86%B5%E7%9B%91%E5%90%AC"><span class="toc-text">网络状况监听</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%A3%80%E6%B5%8B%E5%85%83%E7%B4%A0%E7%9A%84%E5%8F%AF%E8%A7%81%E7%8A%B6%E6%80%81%EF%BC%8C%E5%81%9A%E6%9B%9D%E5%85%89%E5%9F%8B%E7%82%B9"><span class="toc-text">检测元素的可见状态，做曝光埋点</span></a></li></ol></li></ol>
</div>
            </main>
            <aside class="right-column">
              <div class="sticky-widescreen">
  
  
    <article class="card card-content toc-card">
      <div class="toc-header">
  <i 
    class="iconfont icon-menu" 
    style="padding-right: 2px;">
  </i>目录
</div>
<ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%80%A7%E8%83%BD%E6%8C%87%E6%A0%87%E5%92%8C%E4%BC%98%E5%8C%96%E7%9B%AE%E6%A0%87%E4%B9%8B%EF%BC%9A%E5%8A%A0%E8%BD%BD"><span class="toc-text">性能指标和优化目标之：加载</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%89%93%E5%BC%80%E7%BD%91%E7%AB%99%E7%9A%84%E5%88%9D%E4%BD%93%E9%AA%8C"><span class="toc-text">打开网站的初体验</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BF%9D%E5%AD%98%E5%BF%AB%E7%85%A7"><span class="toc-text">保存快照</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%80%91%E5%B8%83%E5%9B%BE-Waterfall"><span class="toc-text">瀑布图 Waterfall</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%80%A7%E8%83%BD%E6%8C%87%E6%A0%87%E5%92%8C%E4%BC%98%E5%8C%96%E7%9B%AE%E6%A0%87%E4%B9%8B%EF%BC%9A%E4%BA%A4%E4%BA%92"><span class="toc-text">性能指标和优化目标之：交互</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#FPS%E5%B8%A7%E7%8E%87%E3%80%81FRS"><span class="toc-text">FPS帧率、FRS</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%94%A8-RAIL-%E6%A8%A1%E5%9E%8B%E6%B5%8B%E9%87%8F%E6%80%A7%E8%83%BD"><span class="toc-text">用 RAIL 模型测量性能</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1%E3%80%81%E5%93%8D%E5%BA%94"><span class="toc-text">1、响应</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2%E3%80%81%E5%8A%A8%E7%94%BB"><span class="toc-text">2、动画</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3%E3%80%81%E7%A9%BA%E9%97%B2%E6%97%B6%E9%97%B4"><span class="toc-text">3、空闲时间</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4%E3%80%81%E5%8A%A0%E8%BD%BD"><span class="toc-text">4、加载</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8Chrome-DevTools-%E5%88%86%E6%9E%90%E6%80%A7%E8%83%BD"><span class="toc-text">使用Chrome DevTools 分析性能</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#size%EF%BC%9A%E6%96%87%E4%BB%B6%E5%A4%A7%E5%B0%8F%E5%88%86%E6%9E%90"><span class="toc-text">size：文件大小分析</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#performance%EF%BC%9A%E6%80%A7%E8%83%BD%E8%A1%A8%E7%8E%B0"><span class="toc-text">performance：性能表现</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Diable-cache"><span class="toc-text">Diable cache</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%A8%A1%E6%8B%9F%E7%BD%91%E7%BB%9C%E6%83%85%E5%86%B5"><span class="toc-text">模拟网络情况</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Performance-monitor"><span class="toc-text">Performance monitor</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%BF%AB%E6%8D%B7%E9%94%AEESC"><span class="toc-text">快捷键ESC</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8LightHouse%E5%88%86%E6%9E%90%E6%80%A7%E8%83%BD"><span class="toc-text">使用LightHouse分析性能</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Lighthouse-%E4%BB%8B%E7%BB%8D"><span class="toc-text">Lighthouse 介绍</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%BE%E4%BE%8B%EF%BC%9A%E7%A1%AE%E8%AE%A4%E6%9F%90%E4%B8%AAJS-%E6%98%AF%E5%90%A6%E5%BF%85%E9%A1%BB%E5%9C%A8%E9%A6%96%E5%B1%8F%E5%8A%A0%E8%BD%BD"><span class="toc-text">举例：确认某个JS 是否必须在首屏加载</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%80%9A%E8%BF%87npm%E8%BF%90%E8%A1%8C-Lighthouse%E5%B7%A5%E5%85%B7"><span class="toc-text">通过npm运行 Lighthouse工具</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8-WebPageTest-%E8%AF%84%E4%BC%B0%E7%BD%91%E7%AB%99%E6%80%A7%E8%83%BD"><span class="toc-text">使用 WebPageTest 评估网站性能</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#WebPageTest-%E4%BD%BF%E7%94%A8"><span class="toc-text">WebPageTest 使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#WebPageTest-%E6%8A%A5%E5%91%8A%E5%88%86%E6%9E%90"><span class="toc-text">WebPageTest 报告分析</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B1%80%E5%9F%9F%E7%BD%91%E9%83%A8%E7%BD%B2-WebPageTest-%E5%B7%A5%E5%85%B7"><span class="toc-text">局域网部署 WebPageTest 工具</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#chrome%E6%8F%92%E4%BB%B6%EF%BC%9APageSpeed-Insights"><span class="toc-text">chrome插件：PageSpeed Insights</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AE%9E%E6%97%B6%E5%8A%A8%E6%80%81%E6%B5%8B%E9%87%8F%E6%80%A7%E8%83%BD%E7%9A%84API"><span class="toc-text">实时动态测量性能的API</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#performance%EF%BC%9A%E8%8E%B7%E5%8F%96%E5%B8%B8%E8%A7%81%E6%80%A7%E8%83%BD%E5%8F%82%E6%95%B0"><span class="toc-text">performance：获取常见性能参数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%A7%82%E5%AF%9F%E9%95%BF%E4%BB%BB%E5%8A%A1"><span class="toc-text">观察长任务</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%A1%B5%E9%9D%A2%E5%8F%AF%E8%A7%81%E6%80%A7%E7%9A%84%E7%8A%B6%E6%80%81%E7%9B%91%E5%90%AC"><span class="toc-text">页面可见性的状态监听</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BD%91%E7%BB%9C%E7%8A%B6%E5%86%B5%E7%9B%91%E5%90%AC"><span class="toc-text">网络状况监听</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%A3%80%E6%B5%8B%E5%85%83%E7%B4%A0%E7%9A%84%E5%8F%AF%E8%A7%81%E7%8A%B6%E6%80%81%EF%BC%8C%E5%81%9A%E6%9B%9D%E5%85%89%E5%9F%8B%E7%82%B9"><span class="toc-text">检测元素的可见状态，做曝光埋点</span></a></li></ol></li></ol>
    </article>
  
  
  <article class="card card-content">
    <div class="recent-posts-card">
  <div class="recent-posts-header">
    <i 
      class="iconfont icon-wenzhang_huaban" 
      style="padding-right: 2px;">
    </i>最近文章
  </div>
  <div class="recent-posts-list">
    
      <div class="recent-posts-item">
        <div class="recent-posts-item-title">2023-03-09</div>
        <a href="/2023/03/09/13-React%E5%9F%BA%E7%A1%80/11-React%20Navive%E5%88%9D%E8%AF%86/"><div class="recent-posts-item-content">11-React Navive初识</div></a>
      </div>
    
      <div class="recent-posts-item">
        <div class="recent-posts-item-title">2023-03-09</div>
        <a href="/2023/03/09/13-React%E5%9F%BA%E7%A1%80/10-AntD%E6%A1%86%E6%9E%B6%E7%9A%84upload%E7%BB%84%E4%BB%B6%E4%B8%8A%E4%BC%A0%E5%9B%BE%E7%89%87%E6%97%B6%E4%BD%BF%E7%94%A8customRequest%E6%96%B9%E6%B3%95%E8%87%AA%E5%AE%9A%E4%B9%89%E4%B8%8A%E4%BC%A0%E8%A1%8C%E4%B8%BA/"><div class="recent-posts-item-content">10-AntD框架的upload组件上传图片时使用customRequest方法自定义上传行为</div></a>
      </div>
    
      <div class="recent-posts-item">
        <div class="recent-posts-item-title">2023-03-09</div>
        <a href="/2023/03/09/13-React%E5%9F%BA%E7%A1%80/09-AntD%E6%A1%86%E6%9E%B6%E7%9A%84upload%E7%BB%84%E4%BB%B6%E4%B8%8A%E4%BC%A0%E5%9B%BE%E7%89%87%E6%97%B6%E9%81%87%E5%88%B0%E7%9A%84%E4%B8%80%E4%BA%9B%E5%9D%91/"><div class="recent-posts-item-content">09-AntD框架的upload组件上传图片时遇到的一些坑</div></a>
      </div>
    
      <div class="recent-posts-item">
        <div class="recent-posts-item-title">2023-03-09</div>
        <a href="/2023/03/09/13-React%E5%9F%BA%E7%A1%80/08-Ant%20Design%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8/"><div class="recent-posts-item-content">08-Ant Design的基本使用</div></a>
      </div>
    
  </div>
</div>
  </article>
  
  
</div>
            </aside>
          </div>
        </div>
      </div>
    </div>
     
    <footer class="footer">
  <div class="footer-container">
    <div>
      <div class="footer-dsc">
        <span>
          Copyright ©
          
            2023
          
          
        </span>
        &nbsp;
        <a 
          href="/" 
          class="footer-link">
          前端面试
        </a>
      </div>
    </div>

    
      <div class="footer-dsc">
        
          Powered by
          <a 
            href="https://hexo.io/" 
            class="footer-link" 
            target="_blank" 
            rel="nofollow noopener noreferrer">
            &nbsp;Hexo
          </a>
        
        
          <span>&nbsp;|&nbsp;</span>
        
        
          Theme -
          <a 
            href="https://github.com/theme-kaze" 
            class="footer-link" 
            target="_blank"
            rel="nofollow noopener noreferrer">
            &nbsp;Kaze
          </a>
        
      </div>
    
    
    
    
</footer>
 
    
  <a 
    role="button" 
    id="scrollbutton" 
    class="basebutton" 
    aria-label="回到顶部">
    <i class="iconfont icon-arrowleft button-icon"></i>
  </a>

<a 
  role="button" 
  id="menubutton"
  aria-label="menu button"
  class="basebutton">
  <i class="iconfont icon-menu button-icon"></i>
</a>
<a 
  role="button" 
  id="popbutton" 
  class="basebutton" 
  aria-label="控制中心">
  <i class="iconfont icon-expand button-icon"></i>
</a>
<a 
  role="button" 
  id="darkbutton" 
  class="basebutton darkwidget" 
  aria-label="夜色模式">
  <i class="iconfont icon-weather button-icon"></i>
</a>
<a 
  role="button" 
  id="searchbutton" 
  class="basebutton searchwidget" 
  aria-label="搜索">
  <i class="iconfont icon-search button-icon"></i>
</a> 
     
     
     
      <script>
  var addImgLayout = function () {
    var img = document.querySelectorAll('.post-content img')
    var i
    for (i = 0; i < img.length; i++) {
      var wrapper = document.createElement('a')
      wrapper.setAttribute('href', img[i].getAttribute('data-src'))
      wrapper.setAttribute('aria-label', 'illustration')
      wrapper.style.cssText =
        'width: 100%; display: flex; justify-content: center;'
      if (img[i].alt) wrapper.dataset.caption = img[i].alt
      wrapper.dataset.nolink = true
      img[i].before(wrapper)
      wrapper.append(img[i])
      var divWrap = document.createElement('div')
      divWrap.classList.add('gallery')
      wrapper.before(divWrap)
      divWrap.append(wrapper)
    }
    baguetteBox.run('.gallery')
  }
</script>
<script>
  loadScript(
    "/js/lib/lightbox/baguetteBox.min.js",
    addImgLayout
  )
</script>
 
     
     
    <script src="/js/main.js"></script> 
     
    
      <script>
        var addLazyload = function () {
          var observer = lozad('.lozad', {
            load: function (el) {
              el.srcset = el.getAttribute('data-src')
            },
            loaded: function (el) {
              el.classList.add('loaded')
            },
          })
          observer.observe()
        }
      </script>
      <script>
        loadScript('/js/lib/lozad.min.js', addLazyload)
      </script>
    
    <script src="//instant.page/5.1.0" type="module"
      integrity="sha384-by67kQnR+pyfy8yWP4kPO12fHKRLHZPfEsiSXR8u2IKcTdxD805MGUXBzVPnkLHw"></script>
    
    
  </body>
</html>
